package com.tank.frame;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import com.tank.designstudy.strategy.DefaultFireStrategy;
import com.tank.model.DirEnum;
import com.tank.model.GameModel;

public class TankFrame extends Frame {

	private GameModel gameModel;

	public TankFrame(GameModel gameModel) {
		this.gameModel = gameModel;

		setTitle("Tank War");
		setSize(GameModel.GAME_WIDTH, GameModel.GAME_HEIGHT);
		setResizable(false);
		setVisible(true);

		/**
		 * 添加窗口监听，点击关闭按钮时关闭程序
		 */
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {// 监听关闭按钮
				System.exit(0);
			}
		});

		/**
		 * 添加键盘监听，监听通过继承KeyAdapter的内部类实现
		 */
		this.addKeyListener(new MyKeyListener());
	}

	// 内部类 处理键盘事件 内部类好处：1.其他类访问不到一个类的内部类，具有良好的封装性 2.内部类调用它的外部类成员及方法很方便
	class MyKeyListener extends KeyAdapter {
		boolean lk = false;
		boolean rk = false;
		boolean uk = false;
		boolean dk = false;

		@Override
		public void keyPressed(KeyEvent e) {
			// 获取键盘点击的keycode
			int key = e.getKeyCode();
			// 根据keycode设置相应方向为true
			switch (key) {
			case KeyEvent.VK_LEFT:
				lk = true;
				break;
			case KeyEvent.VK_RIGHT:
				rk = true;
				break;
			case KeyEvent.VK_UP:
				uk = true;
				break;
			case KeyEvent.VK_DOWN:
				dk = true;
				break;
			default:
				break;
			}
			// 根据方向标记布尔值设置坦克行进方向
			setMainDir();
		}

		@Override
		public void keyReleased(KeyEvent e) {
			// 键盘释放
			int key = e.getKeyCode();

			switch (key) {
			case KeyEvent.VK_LEFT:
				lk = false;
				break;
			case KeyEvent.VK_RIGHT:
				rk = false;
				break;
			case KeyEvent.VK_UP:
				uk = false;
				break;
			case KeyEvent.VK_DOWN:
				dk = false;
				break;
			case KeyEvent.VK_CONTROL:
				gameModel.getMainTank().fire(DefaultFireStrategy.getInstance());
			default:
				break;
			}

			// 根据方向标记布尔值设置坦克行进方向
			setMainDir();
		}

		/**
		 * 设置主战坦克行进方向
		 */
		private void setMainDir() {
			if (!lk && !rk && !uk && !dk) {
				gameModel.getMainTank().setMoving(false);
			} else {
				gameModel.getMainTank().setMoving(true);
				if (lk) {
					gameModel.getMainTank().setDir(DirEnum.LEFT);
				}
				if (rk) {
					gameModel.getMainTank().setDir(DirEnum.RIGHT);
				}
				if (uk) {
					gameModel.getMainTank().setDir(DirEnum.UP);
				}
				if (dk) {
					gameModel.getMainTank().setDir(DirEnum.DOWN);
				}
			}
		}
	}

	@Override
	// 窗口需要***重新绘制***的时候，会调用此方法,清空 然后重画
	public void paint(Graphics g) {
		gameModel.paint(g);
	}

	/**
	 * 双缓冲解决屏幕闪烁问题 通过在内存中缓冲绘制过程，等过程结束，再交给系统画笔将画面一次绘制出来
	 */
	private Image offScreenImage = null;

	@Override
	public void update(Graphics g) {
		if (offScreenImage == null) {
			this.offScreenImage = this.createImage(GameModel.GAME_WIDTH, GameModel.GAME_HEIGHT);
		}
		Graphics gOffScreen = offScreenImage.getGraphics();
		Color c = gOffScreen.getColor();
		gOffScreen.setColor(Color.BLACK);
		gOffScreen.fillRect(0, 0, GameModel.GAME_WIDTH, GameModel.GAME_HEIGHT);
		gOffScreen.setColor(c);
		paint(gOffScreen);
		g.drawImage(offScreenImage, 0, 0, null);
	}

}
